﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ESRI.ArcGIS.Carto;
using System.Data;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using System.Windows.Forms;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.esriSystem;

namespace ComponentGIS.Class
{
    class BasicClass
    {
        /// <summary>
        /// 从工作空间添加图层
        /// </summary>
        /// <param name="pWorkspace">工作空间</param>
        /// <param name="axMapControl">地图控件</param>
        public static void AddLayersFromWorkspace(IWorkspace pWorkspace, AxMapControl axMapControl)
        {
            try
            {
                IEnumDataset pEnumDataset = pWorkspace.get_Datasets(esriDatasetType.esriDTAny);
                pEnumDataset.Reset();
                IDataset pDataset = pEnumDataset.Next();
                while (pDataset != null)
                {
                    switch (pDataset.Type)
                    {
                        case esriDatasetType.esriDTFeatureClass:    //要素类
                            {
                                IFeatureWorkspace pFeatureWorkspace = (IFeatureWorkspace)pWorkspace;
                                IFeatureClass pFeaCls = pFeatureWorkspace.OpenFeatureClass(pDataset.Name);
                                IFeatureLayer pFeaLyr = new FeatureLayerClass();
                                pFeaLyr.FeatureClass = pFeaCls;
                                axMapControl.Map.AddLayer(pFeaLyr);
                            }
                            break;
                        case esriDatasetType.esriDTFeatureDataset:  //要素集
                            {
                                IFeatureWorkspace pFeatureWorkspace = (IFeatureWorkspace)pWorkspace;
                                IFeatureDataset pFeaDataset = pFeatureWorkspace.OpenFeatureDataset(pDataset.Name);
                                IEnumDataset pEnumFeatureDataset = pFeaDataset.Subsets;
                                pEnumFeatureDataset.Reset();
                                IDataset pDatasetNew = pEnumFeatureDataset.Next();
                                while (pDatasetNew != null)
                                {
                                    if (pDatasetNew is IFeatureClass)
                                    {
                                        IFeatureClass pFeaCls = pFeatureWorkspace.OpenFeatureClass(pDatasetNew.Name);
                                        IFeatureLayer pFeaLyr = new FeatureLayerClass();
                                        pFeaLyr.FeatureClass = pFeaCls;
                                        axMapControl.Map.AddLayer(pFeaLyr);
                                    }
                                    pDatasetNew = pEnumFeatureDataset.Next();
                                }
                            }
                            break;
                        case esriDatasetType.esriDTRasterDataset:   //栅格集
                            MessageBox.Show("还没写哦！");
                            break;
                        case esriDatasetType.esriDTTable:           //表格
                            MessageBox.Show("还没写哦！");
                            break;
                        case esriDatasetType.esriDTTopology:        //拓扑
                            MessageBox.Show("还没写哦！");
                            break;
                        default:
                            MessageBox.Show("还没写哦！");
                            break;
                    }
                    pDataset = pEnumDataset.Next();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// 获取地图单位
        /// </summary>
        public static string GetMapUnit(esriUnits mapUnit)
        {
            string sMapUnit = string.Empty;
            switch (mapUnit)
            {
                case esriUnits.esriCentimeters:
                    sMapUnit = "厘米";
                    break;
                case esriUnits.esriDecimalDegrees:
                    sMapUnit = "十进制";
                    break;
                case esriUnits.esriDecimeters:
                    sMapUnit = "分米";
                    break;
                case esriUnits.esriFeet:
                    sMapUnit = "尺";
                    break;
                case esriUnits.esriInches:
                    sMapUnit = "英寸";
                    break;
                case esriUnits.esriKilometers:
                    sMapUnit = "千米";
                    break;
                case esriUnits.esriMeters:
                    sMapUnit = "米";
                    break;
                case esriUnits.esriMiles:
                    sMapUnit = "英里";
                    break;
                case esriUnits.esriMillimeters:
                    sMapUnit = "毫米";
                    break;
                case esriUnits.esriNauticalMiles:
                    sMapUnit = "海里";
                    break;
                case esriUnits.esriPoints:
                    sMapUnit = "点";
                    break;
                case esriUnits.esriUnitsLast:
                    sMapUnit = "UnitsLast";
                    break;
                case esriUnits.esriUnknownUnits:
                    sMapUnit = "未知单位";
                    break;
                case esriUnits.esriYards:
                    sMapUnit = "码";
                    break;
                default:
                    sMapUnit = "未知单位";
                    break;
            }
            return sMapUnit;
        }

        /// <summary>
        /// 获取几何类型(中文)
        /// </summary>
        /// <param name="geometryType">几何类型</param>
        private static string GetGeometryType(esriGeometryType geometryType)
        {
            string sGeoType = string.Empty;
            switch (geometryType)
            {
                case esriGeometryType.esriGeometryNull:
                    break;
                case esriGeometryType.esriGeometryPoint:
                    sGeoType = "点";
                    break;
                case esriGeometryType.esriGeometryMultipoint:
                    sGeoType = "点集";
                    break;
                case esriGeometryType.esriGeometryLine:
                    sGeoType = "线";
                    break;
                case esriGeometryType.esriGeometryCircularArc:
                    sGeoType = "圆弧";
                    break;
                case esriGeometryType.esriGeometryEllipticArc:
                    break;
                case esriGeometryType.esriGeometryBezier3Curve:
                    sGeoType = "贝塞尔曲线";
                    break;
                case esriGeometryType.esriGeometryPath:
                    sGeoType = "折线";
                    break;
                case esriGeometryType.esriGeometryPolyline:
                    sGeoType = "折线";
                    break;
                case esriGeometryType.esriGeometryRing:
                    sGeoType = "环";
                    break;
                case esriGeometryType.esriGeometryPolygon:
                    sGeoType = "面";
                    break;
                case esriGeometryType.esriGeometryEnvelope:
                    sGeoType = "包围盒";
                    break;
                case esriGeometryType.esriGeometryAny:
                    break;
                case esriGeometryType.esriGeometryBag:
                    break;
                case esriGeometryType.esriGeometryMultiPatch:
                    break;
                case esriGeometryType.esriGeometryTriangleStrip:
                    break;
                case esriGeometryType.esriGeometryTriangleFan:
                    break;
                case esriGeometryType.esriGeometryRay:
                    break;
                case esriGeometryType.esriGeometrySphere:
                    break;
                case esriGeometryType.esriGeometryTriangles:
                    break;
                default:
                    break;
            }
            return sGeoType;
        }

        /// <summary>
        /// 获取属性表
        /// </summary>
        /// <param name="pFeaCur">游标</param>
        public static DataTable GetAttributeTable(IFeatureCursor pFeaCur)
        {
            DataTable pDataTable = new DataTable();
            IFeature pFea = pFeaCur.NextFeature();
            //1. 填充字段名
            for (int i = 0; i < pFea.Fields.FieldCount; i++)
                pDataTable.Columns.Add(pFea.Fields.get_Field(i).Name);
            //2. 填充要素
            while (pFea != null)
            {
                object[] rowValueArray = new object[pFea.Fields.FieldCount];
                for (int i = 0; i < pFea.Fields.FieldCount; i++)
                {
                    object fieldValue;
                    if (pFea.Fields.get_Field(i).Name == "Shape")
                        fieldValue = GetGeometryType(pFea.Shape.GeometryType);
                    else
                        fieldValue = pFea.get_Value(i);
                    rowValueArray[i] = fieldValue;
                }
                pDataTable.LoadDataRow(rowValueArray, true);
                pFea = pFeaCur.NextFeature();
            }
            return pDataTable;
        }

        /// <summary>
        /// 获取要素图层名称集合
        /// </summary>
        /// <param name="pMap">地图</param>
        static public List<string> GetFeatureLayerNameList(IMap pMap)
        {
            List<string> layerNameList = new List<string>();
            for (int i = 0; i < pMap.LayerCount; i++)
                layerNameList.Add(pMap.get_Layer(i).Name);
            return layerNameList;
        }

        /// <summary>
        /// 获取可选要素图层名称集合
        /// </summary>
        /// <param name="pMap">地图</param>
        static public List<string> GetSelectableLayerNameList(IMap pMap)
        {
            List<string> layerNameList = new List<string>();
            for (int i = 0; i < pMap.LayerCount; i++)
            {
                IFeatureLayer pFeaLyr = (IFeatureLayer)pMap.get_Layer(i);
                if (pFeaLyr.Selectable)
                    layerNameList.Add(pFeaLyr.Name);
            }
            return layerNameList;
        }

        /// <summary>
        /// 获取要素图层
        /// </summary>
        /// <param name="pMap">地图</param>
        /// <param name="sLyrName">图层名</param>
        /// <returns></returns>
        static public IFeatureLayer GetFeatureLayer(IMap pMap, string sLyrName)
        {
            IFeatureLayer pFeaLyr = null;
            for (int i = 0; i < pMap.LayerCount; i++)
            {
                ILayer pLyr = pMap.get_Layer(i);
                if (pLyr.Name == sLyrName)
                    pFeaLyr = (IFeatureLayer)pLyr;
            }
            return pFeaLyr;
        }

        /// <summary>
        /// 获取选择集图层名称
        /// </summary>
        /// <param name="pMap">地图</param>
        /// <returns>选择集图层名称</returns>
        static public List<string> GetFeatureSelectionNameList(IMap pMap)
        {
            List<string> pFeaSelectionNameList = new List<string>();
            for (int i = 0; i < pMap.LayerCount; i++)
            {
                IFeatureLayer pFeaLyr = (IFeatureLayer)pMap.get_Layer(i);
                IFeatureSelection pFeaSel = (IFeatureSelection)pFeaLyr;
                if (pFeaSel.SelectionSet.Count != 0)
                    pFeaSelectionNameList.Add(pFeaLyr.Name);
            }
            return pFeaSelectionNameList;
        }

        public static List<int> GetFeatureLayerOIDList(IFeatureSelection pFeaSel)
        {
            try
            {
                List<int> OIDList = new List<int>();
                ISelectionSet pSelSet = pFeaSel.SelectionSet;
                IEnumIDs pOIDs = pSelSet.IDs;
                int OID = pOIDs.Next();
                while (OID > 0)
                {
                    OIDList.Add(OID);
                    OID = pOIDs.Next();
                }
                return OIDList;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return null;
            }
        }

        /// <summary>
        /// 获取字段名集合
        /// </summary>
        /// <param name="pFeaCls">要素类</param>
        static public List<string> GetFieldNameList(IFeatureClass pFeaCls)
        {
            List<string> fieldsName = new List<string>();
            for (int i = 0; i < pFeaCls.Fields.FieldCount; i++)
                fieldsName.Add(pFeaCls.Fields.get_Field(i).Name);
            return fieldsName;
        }

        /// <summary>
        /// 获取字段值集合
        /// </summary>
        /// <param name="pFeaCls">要素类</param>
        /// <param name="sFieldName">字段名</param>
        static public List<string> GetFieldValueList(IFeatureClass pFeaCls, string sFieldName)
        {
            List<string> fieldValueList = new List<string>();
            IDataset dataset = (IDataset)pFeaCls;
            IQueryDef queryDef = ((IFeatureWorkspace)dataset.Workspace).CreateQueryDef();
            queryDef.Tables = dataset.Name;
            queryDef.SubFields = "DISTINCT (" + sFieldName + ")";
            ICursor cursor = queryDef.Evaluate();
            IRow row = cursor.NextRow();
            while (row != null)
            {
                fieldValueList.Add(row.get_Value(0).ToString());
                row = cursor.NextRow();
            }
            return fieldValueList;
        }

        /// <summary>
        /// 属性查询
        /// </summary>
        /// <param name="pFeaLyr">查询图层</param>
        /// <param name="Method">选择方式</param>
        /// <param name="WhereClause">查询语句</param>
        /// <param name="pActiveView">活动视图</param>
        static public bool SelectFeatures(IFeatureLayer pFeaLyr, esriSelectionResultEnum Method,
            string WhereClause, IActiveView pActiveView)
        {
            try
            {
                IFeatureSelection pFeaSelection = (IFeatureSelection)pFeaLyr;
                IQueryFilter pQF = new QueryFilterClass();
                pQF.WhereClause = WhereClause;
                pFeaSelection.SelectFeatures(pQF, Method, false);
                if (pFeaSelection.SelectionSet.Count == 0)
                    return false;
                pActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, null, null);
                return true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
                return false;
            }
        }

        /// <summary>
        /// 空间查询
        /// </summary>
        /// <param name="pFeaTargetLyr">目标图层</param>
        /// <param name="Method">选择方式</param>
        /// <param name="spatialRel">空间关系</param>
        /// <param name="pGeo">源图层几何属性</param>
        /// <param name="pActiveView">活动视图</param>
        static public bool SelectFeatures(esriSelectionResultEnum Method, esriSpatialRelEnum spatialRel,
            IGeometry pGeo, IFeatureLayer pFeaTargetLyr, IActiveView pActiveView)
        {
            try
            {
                IFeatureSelection pFeaSelection = (IFeatureSelection)pFeaTargetLyr;
                ISpatialFilter pSF = new SpatialFilterClass();
                pSF.Geometry = pGeo;
                pSF.SpatialRel = spatialRel;
                pFeaSelection.SelectFeatures(pSF, Method, false);
                if (pFeaSelection.SelectionSet.Count == 0)
                    return false;
                pActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, null, null);
                return true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
                return false;
            }
        }

        /// <summary>
        /// 要素图形属性合并
        /// </summary>
        /// <param name="pFeaSelection">选择集</param>
        static public IGeometry GetGeoUnion(IFeatureSelection pFeaSelection)
        {
            try
            {
                IGeometry pGeo = null;
                ISelectionSet pSelSet = pFeaSelection.SelectionSet;
                ICursor pCur;
                pSelSet.Search(null, false, out pCur);
                IFeatureCursor pFeaCur = (IFeatureCursor)pCur;
                IFeature pFea = pFeaCur.NextFeature();
                while (pFea != null)
                {
                    if (pGeo != null)
                    {
                        ITopologicalOperator pTopoOp = (ITopologicalOperator)pGeo;
                        pGeo = pTopoOp.Union(pFea.Shape);
                    }
                    else
                        pGeo = pFea.Shape;
                    pFea = pFeaCur.NextFeature();
                }
                return pGeo;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return null;
            }
        }


    }
}
